package com.woniuxy.meal.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.meal.common.ConstantData;
import com.woniuxy.meal.common.RedisKey;
import com.woniuxy.meal.dao.FoodVarietyMapper;
import com.woniuxy.meal.entity.StoreInfo;
import com.woniuxy.meal.service.StoreInfoService;
import com.woniuxy.meal.service.dto.SubmitCartDto;
import com.woniuxy.meal.entity.FoodVariety;
import com.woniuxy.meal.entity.UserCart;
import com.woniuxy.meal.dao.UserCartMapper;
import com.woniuxy.meal.exception.FoodVarietyException.FoodVarietyException;
import com.woniuxy.meal.exception.FoodVarietyException.FoodVarietyExceptionCode;
import com.woniuxy.meal.exception.userCartException.UserCartException;
import com.woniuxy.meal.exception.userCartException.UserCartExceptionCode;
import com.woniuxy.meal.form.AddCartForm;
import com.woniuxy.meal.form.SubmitCartForm;
import com.woniuxy.meal.form.UpdateCartForm;
import com.woniuxy.meal.service.FoodVarietyService;
import com.woniuxy.meal.service.UserCartService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.meal.service.dto.StoreCartDto;
import com.woniuxy.meal.service.dto.UserCartDto;
import com.woniuxy.meal.util.RedisUtil;
import com.woniuxy.meal.util.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * <p>
 * 用户购物车表 服务实现类
 * </p>
 *
 * @author zz
 * @since 2023年06月16日
 */
@Service
public class UserCartServiceImpl extends ServiceImpl<UserCartMapper, UserCart> implements UserCartService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private TimeUtil timeUtil;

    @Autowired
    private StoreInfoService storeInfoService;

    @Autowired
    private FoodVarietyMapper foodVarietyMapper;

    @Autowired
    private FoodVarietyService foodVarietyService;



    @Override
    public void addCart(AddCartForm form, Long userId) throws Exception{
        String userCartKey = RedisKey.getUserCartKey(userId);
        //先判断参数中的foodid是否存在
        FoodVariety foodVariety = foodVarietyService.getById(form.getFoodId());
        if (foodVariety==null||foodVariety.getState() != ConstantData.FOOD_TYPE_STATE_NORMAL){
            throw  new FoodVarietyException(FoodVarietyExceptionCode.FOOD_NOT_EXIST);
        }
        //判断该用户购物车中是否有该食品项
        String cartInfoKey = RedisKey.getCartInfoKey(form.getFoodId());
        String cartInfo = (String) redisUtil.hsGet(userCartKey, cartInfoKey);
        if (cartInfo==null||cartInfo.equals("")){
            //购物车中不存在该食品
            UserCart userCart = BeanUtil.toBean(foodVariety, UserCart.class);
            userCart.setFoodId(foodVariety.getId());
            userCart.setId(IdUtil.getSnowflake().nextId());
            userCart.setCount(form.getCount());
            cartInfo = JSONUtil.toJsonStr(userCart);
            redisUtil.hsPut(userCartKey,cartInfoKey,cartInfo);
        }else {
            //购物车中存在该食品，在原来的数量基础上添加参数中的数量
            UserCart userCart = JSONUtil.toBean(cartInfo, UserCart.class);
            userCart.setCount(userCart.getCount()+ form.getCount());
            cartInfo = JSONUtil.toJsonStr(userCart);
            redisUtil.hsPut(userCartKey,cartInfoKey,cartInfo);
        }
    }

    @Override
    public void updateCart(UpdateCartForm form, Long userId) throws Exception{
        //先判断参数中的foodid是否存在
        FoodVariety foodVariety = foodVarietyService.getById(form.getFoodId());
        if (foodVariety==null||foodVariety.getState() != ConstantData.FOOD_TYPE_STATE_NORMAL){
            throw  new FoodVarietyException(FoodVarietyExceptionCode.FOOD_NOT_EXIST);
        }
        //判断该用户的购物车中是否有这条记录
        String userCartKey = RedisKey.getUserCartKey(userId);
        String cartInfoKey = RedisKey.getCartInfoKey(form.getFoodId());
        String cartInfo = (String) redisUtil.hsGet(userCartKey, cartInfoKey);
        if (cartInfo==null||cartInfo.equals("")){
            throw new UserCartException(UserCartExceptionCode.USER_CART_NOT_EXIST);
        }
        UserCart userCart = JSONUtil.toBean(cartInfo, UserCart.class);
        System.out.println("更新数量："+form.getCount());
        if (form.getCount()==0){
            //删除该条购物车信息
            redisUtil.hsDel(userCartKey, cartInfoKey);
            return;
        }
        //直接将食品数量修改为传入的值
        userCart.setCount(form.getCount());
        //将更新后的数量存入redis中
        String jsonStr = JSONUtil.toJsonStr(userCart);
        redisUtil.hsPut(userCartKey, cartInfoKey,jsonStr);
    }

    @Override
    public void deleteCart(String foodIds, Long userId) throws Exception{
        String[] ids = foodIds.split(",");
        if (ids.length==0){
            throw new UserCartException(UserCartExceptionCode.USER_CART_NOT_EXIST);
        }
        for (String id : ids) {
            //先判断参数中的foodid是否存在
            FoodVariety foodVariety = foodVarietyService.getById(Long.parseLong(id));
            if (foodVariety==null||foodVariety.getState() != ConstantData.FOOD_TYPE_STATE_NORMAL){
                throw  new FoodVarietyException(FoodVarietyExceptionCode.FOOD_NOT_EXIST);
            }
            //判断该用户的购物车中是否有这条记录
            String userCartKey = RedisKey.getUserCartKey(userId);
            String cartInfoKey = RedisKey.getCartInfoKey(Long.parseLong(id));
            String cartInfo = (String) redisUtil.hsGet(userCartKey, cartInfoKey);
            if (cartInfo==null||cartInfo.equals("")){
                throw new UserCartException(UserCartExceptionCode.USER_CART_NOT_EXIST);
            }
        }
        String userCartKey = RedisKey.getUserCartKey(userId);
        for (String id : ids) {
            String cartInfoKey = RedisKey.getCartInfoKey(Long.parseLong(id));
            //删除redis中对应的购物车信息
            redisUtil.hsDel(userCartKey, cartInfoKey);
        }

    }

    @Override
    public List<UserCartDto> showCart(Long userId) throws Exception{
        List<UserCartDto> list = new ArrayList<>();
        String userCartKey = RedisKey.getUserCartKey(userId);
        if(!redisUtil.exist(userCartKey)){
            return null;
        }
        List<Object> objects = redisUtil.hsGetValues(userCartKey);
        HashSet<Long> storeIds = new HashSet<>();
        for (Object usc : objects) {
            UserCart userCart = JSONUtil.toBean(String.valueOf(usc),UserCart.class);
            storeIds.add(userCart.getStoreId());
        }
        for (Long storeId : storeIds) {
            UserCartDto userCartDto = new UserCartDto();
            List<StoreCartDto> storeCarts = new ArrayList<>();
            for (Object usc : objects) {
                UserCart userCart = JSONUtil.toBean(String.valueOf(usc),UserCart.class);
                if (userCart.getStoreId().longValue()==storeId.longValue()){
                    userCartDto.setStoreId(storeId);
                    userCartDto.setStoreName(userCart.getStoreName());
                    StoreCartDto storeCartDto = BeanUtil.toBean(userCart, StoreCartDto.class);
                    storeCarts.add(storeCartDto);
                }
            }
            userCartDto.setList(storeCarts);
            list.add(userCartDto);
        }

        return list;
    }

    @Override
    public SubmitCartDto submitCart(SubmitCartForm form,Long userId) throws Exception {
        StoreInfo storeInfo = storeInfoService.getById(form.getStoreId());
        //判断店铺状态
        if ((storeInfo==null)||(storeInfo.getDeleteFlag()!= 0)){
            throw new UserCartException(UserCartExceptionCode.STORE_STATE_ERROR);
        }
        if (storeInfo.getStoreStatus()!=ConstantData.STORE_STATE_OPEN){
            throw new UserCartException(UserCartExceptionCode.STORE_STATE_CLOSE);
        }
        //判断当前时间是否在店铺营业时间范围内
        timeUtil.compareOpenTime(storeInfo);
        //订单价格
        BigDecimal price = new BigDecimal(0);
        //判断提交的食品状态
        QueryWrapper<FoodVariety> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",form.getFoodIds());
        queryWrapper.eq("storeId",form.getStoreId());
        queryWrapper.eq("state",ConstantData.FOOD_TYPE_STATE_NORMAL);
        List<FoodVariety> foodVarieties = foodVarietyMapper.selectList(queryWrapper);
        if (foodVarieties.size()!=form.getFoodIds().size()){
            throw new UserCartException(UserCartExceptionCode.FOOD_NOT_EXIST);
        }
        List<StoreCartDto> items = new ArrayList<>();
        String userCartKey = RedisKey.getUserCartKey(userId);
        for (Long foodId : form.getFoodIds()) {
            String cartInfoKey = RedisKey.getCartInfoKey(foodId);
            Object o = redisUtil.hsGet(userCartKey, cartInfoKey);
            if (o==null){
                throw new UserCartException(UserCartExceptionCode.USER_CART_NOT_EXIST);
            }
            UserCart userCart = JSONUtil.toBean(String.valueOf(o), UserCart.class);
            price = price.add(userCart.getPrice().multiply(BigDecimal.valueOf(userCart.getCount())));
            StoreCartDto storeCartDto = BeanUtil.toBean(userCart, StoreCartDto.class);
            items.add(storeCartDto);
        }

        //判断用户选择配送的方式
        SubmitCartDto submitCartDto = new SubmitCartDto();

        //1.堂食
        if (form.getDispatching()==1){
            submitCartDto.setDphPrice(BigDecimal.valueOf(0));
            submitCartDto.setPackPrice(BigDecimal.valueOf(0));
        }else {
        //2.配送
            //判断商家是否有配送服务
            if (!storeInfo.getDispatching().equals(ConstantData.DISPATCH_SERVER_OPEN+"")){
                throw new UserCartException(UserCartExceptionCode.STORE_NOT_DISPATCH_SERVER);
            }
            //判断当前时间是否在商家的配送时间范围内
            timeUtil.compareDeliveryTime(form.getStoreId());
            //判断价格是否达到起送费
            if (price.doubleValue()<storeInfo.getInitiatePrice().doubleValue()){
                throw new UserCartException(UserCartExceptionCode.FOOD_NOT_MATCH_INITIATE);
            }
            submitCartDto.setDphPrice(storeInfo.getDphPrice());
            submitCartDto.setPackPrice(BigDecimal.valueOf(form.getFoodIds().size()));
            price = price.add(submitCartDto.getPackPrice()).add(submitCartDto.getDphPrice());
        }
        submitCartDto.setStoreId(storeInfo.getId());
        submitCartDto.setPrice(price);
        submitCartDto.setItems(items);
        submitCartDto.setStoreName(storeInfo.getStoreName());
        submitCartDto.setDispatching(form.getDispatching());

        return submitCartDto;
    }

    //展示当前用户某商铺的购物车信息
    @Override
    public UserCartDto showCartByStoreId(Long userId, Long storeId) throws Exception {
        List<UserCartDto> list = new ArrayList<>();
        String userCartKey = RedisKey.getUserCartKey(userId);
        if(!redisUtil.exist(userCartKey)){
            return null;
        }
        List<Object> objects = redisUtil.hsGetValues(userCartKey);
        BigDecimal price = new BigDecimal(0);
        UserCartDto userCartDto = new UserCartDto();
        List<StoreCartDto> storeCarts = new ArrayList<>();
        for (Object usc : objects) {
            UserCart userCart = JSONUtil.toBean(String.valueOf(usc),UserCart.class);
            if (userCart.getStoreId().longValue()==storeId.longValue()){
                userCartDto.setStoreId(storeId);
                userCartDto.setStoreName(userCart.getStoreName());
                StoreCartDto storeCartDto = BeanUtil.toBean(userCart, StoreCartDto.class);
                price = price.add(storeCartDto.getPrice().multiply(BigDecimal.valueOf(storeCartDto.getCount())));
                storeCarts.add(storeCartDto);
            }
        }
        if (storeCarts.size()==0){
            return null;
        }
        userCartDto.setList(storeCarts);
        userCartDto.setPrice(price.toString());
        return userCartDto;
    }


}
